#pragma once
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <sys/types.h>
#include <sys/socket.h>
#include <jsoncpp/json/json.h>

namespace ns_protocol
{
// #define MYSELF 1 // 定义了表示自主实现序列化和反序列化
#define SPACE " "
#define SPACE_LEN strlen(SPACE)
#define SEP "\r\n"
#define SEP_LEN strlen(SEP) //不能是sizeof，否则有坑，sizeof会计算斜杠零
    class Request
    {
    public:
        Request()
        {
        }
        Request(int x, int y, char op)
            : _x(x), _y(y), _op(op)
        {
        }

        ~Request()
        {
        }
        // 1.自主实现
        // 2.使用线程方案
        std::string Serialize()
        {
#ifdef MYSELF
            std::string str;
            str += std::to_string(_x);
            str += SPACE;
            str += _op;
            str += SPACE;
            str += std::to_string(_y);
            return str;

#else
            Json::Value root;
            root["x"] = _x;
            root["y"] = _y;
            root["op"] = _op;
            Json::FastWriter writer;
            return writer.write(root);//进行序列化

#endif
        }

        bool Deserialize(const std::string &package)
        {
#ifdef MYSELF
            std::size_t lpos = package.find(SPACE);
            if (lpos == std::string::npos)
                return false;
            std::size_t rpos = package.rfind(SPACE);
            if (rpos == std::string::npos)
                return false;
            _x = atoi(package.substr(0, lpos).c_str());
            _y = atoi(package.substr(rpos + SPACE_LEN).c_str());
            if (lpos + SPACE_LEN > package.size())
                return false;
            else
                _op = package[lpos + SPACE_LEN];
            return true;
#else
            Json::Value root;
            Json::Reader reader;
            reader.parse(package,root);//进行反序列化
            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _op = root["op"].asInt();
            return true;

#endif
        }

    public:
        int _x;
        int _y;
        char _op;
    };

    class Response
    {
    public:
        Response()
        {
        }
        Response(int result, int code)
            : _result(result), _code(code)
        {
        }

        ~Response()
        {
        }

        std::string Serialize()
        {
#ifdef MYSELF
            std::string s;
            s += std::to_string(_code);
            s += SPACE;
            s += std::to_string(_result);
            return s;

#else
            Json::Value root;
            root["code"] = _code;
            root["result"] = _result;
            Json::FastWriter writer;
            return writer.write(root);//进行序列化
#endif
        }

        bool Deserialize(const std::string &package)
        {
#ifdef MYSELF
            std::size_t pos = package.find(SPACE);
            if (pos == std::string::npos)
                return false;
            _code = atoi(package.substr(0,pos).c_str());
            _result = atoi(package.substr(pos + SPACE_LEN).c_str());
            return true;
#else
            Json::Value root;
            Json::Reader reader;
            reader.parse(package,root);//进行反序列化
            _code = root["code"].asInt();
            _result = root["result"].asInt();
            return true;
#endif
        }

    public:
        int _result; // 计算结果
        int _code;   // 计算结果状态码

        int x_;
        int y_;
        char op_;
    };

    bool Recv(int sock,std::string *out)
    {
        char buffer[1024];
        ssize_t s = recv(sock, buffer, sizeof (buffer)-1, 0);
        if (s > 0)
        {
            buffer[s] = 0;
            *out += buffer;
        }
        else if(s == 0)
        {
            std::cout << " client quit" << std::endl;
            return false;
        }
        else
        {
            std::cout << " recv error" << std::endl;
            return false;
        }
        return true;
    }

    void Send(int sock, const std::string str)
    {
        int n = send(sock, str.c_str(), str.size(), 0);
        if(n < 0)
        {
            std::cout << " send error " << std::endl; 
        }
    }

    std::string Decond(std::string& buffer)
    {
        std::size_t pos = buffer.find(SEP);
        if(pos == std::string::npos) return "";
        int size = atoi(buffer.substr(0,pos).c_str());//求完整报文的长度，有可能不是完整报文
        int surplus = buffer.size() - pos - 2*SEP_LEN;//剩余
        if(surplus >= size)//大于等于一个完整报文，就可以处理
        {
            buffer.erase(0,pos + SEP_LEN);
            std::string s = buffer.substr(0,size);
            buffer.erase(0,size + SEP_LEN);
            return s;        
        }
        else
        {
            return "";
        }
    }

    std::string Encode(std::string& s)
    {
        std::string length = std::to_string(s.size());
        std::string new_package = length;
        new_package += SEP;
        new_package += s;
        new_package += SEP;
        return new_package;
    }
}